#include "app_task.h"
#include "thirdparty/log.c/log.h"
#include <fcntl.h>
#include <sys/stat.h>
#include <mqueue.h>
#include <pthread.h>
#include <stdlib.h>
#include <assert.h>

static mqd_t mqueue = -1;
static pthread_t *background_thread_ptr = NULL;
static int background_thread_count = 0;

// 后台线程，负责执行待执行任务
static void *app_task_executor(void *argv)
{
    assert(argv == NULL);
    Task task;
    while (1)
    {
        int receive_len = mq_receive(mqueue, (char *)&task, sizeof(Task), 0);
        if (receive_len != sizeof(Task))
        {
            continue;
        }
        task.callback(task.argv);
    }
    return NULL;
}

int app_task_init(int executor_count)
{
    background_thread_ptr = malloc(executor_count * sizeof(pthread_t));
    if (!background_thread_ptr)
    {
        log_warn("Not enough memory for task manager");
        return -1;
    }

    // 声明一个mq_attr结构体
    struct mq_attr attr;
    attr.mq_maxmsg = 5;
    attr.mq_msgsize = sizeof(Task);
    // 创建了消息队列
    mqueue = mq_open("/atguigu-gateway-mq", O_CREAT | O_RDWR, 0644, &attr);
    if (mqueue < 0)
    {
        log_warn("Message queue open failed for task manager");
        return -1;
    }

    // 创建executor执行队列中的任务
    for (int i = 0; i < executor_count; i++)
    {
        int result = pthread_create(background_thread_ptr + i, NULL, app_task_executor, NULL);
        if (result < 0)
        {
            log_warn("Backgroud thread %d creation fails", i);
        }
        log_debug("Backgroud thread %d created", i);
    }
    background_thread_count = executor_count;

    return 0;
}

void app_task_registerTask(Task *task)
{
    if (mq_send(mqueue, (char *)task, sizeof(Task), 0) < 0)
    {
        log_warn("Task %p register failed", task);
    }
}

void app_task_wait()
{
    for (int i = 0; i < background_thread_count; i++)
    {
        if (background_thread_ptr[i] > 0)
        {
            pthread_join(background_thread_ptr[i], NULL);
            log_debug("Task executor %d joined", i);
        }
    }
    free(background_thread_ptr);
    log_debug("bg ptr freed");
    // 释放其他资源
    mq_close(mqueue);
    mq_unlink("/atguigu-gateway-mq");
    log_debug("mq deleted");
}

void app_task_close()
{
    for (int i = 0; i < background_thread_count; i++)
    {
        if (background_thread_ptr[i] > 0)
        {
            pthread_cancel(background_thread_ptr[i]);
        }
    }
    log_info("Task manager closed");
}
